﻿<!-- version 11:07_22.09.2010 -->

<!doctype html>


<html xmlns="http://www.w3.org/1999/xhtml">


<head>
  <title>Hello!</title>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>

<body style="height:100%; width:100%; padding:0; margin:0;">

		<canvas id="canvas_demo" width="1000px" height="1000px" style="margin:0px; border: 0;  "></canvas>

<script language="JavaScript" type="text/javascript" src="jquery.js"></script>
<script language="JavaScript" type="text/javascript">
	
	var esboza_points = [
							{ x:348, y:342 },
							{ x:328.5, y:333 },
							{ x:307.5, y:323 },
							{ x:294, y:308},
							{ x:280.5, y:293 },
							{ x:243, y:248.5 },
							{ x:293, y:175.5},
							{ x:343, y:102.5 },
							{ x:513.5, y:77.5 },
							{ x:546, y:161.5 },
							{ x:549, y:174 },
							{ x:539, y:188 },
							{ x:530, y:199},
							{ x:521, y:210 },
							{ x:511, y:222 },
							{ x:502, y:224 },
							{ x:491, y:224 },
							{ x:493, y:196 },
							{ x:484, y:173},
							{ x:475, y:150 },
							{ x:461, y:135 },
							{ x:431, y:138},
							{ x:401, y:141 },
							{ x:370, y:184 },
							{ x:362, y:229},
							{ x:354, y:274 },
							{ x:377, y:309 },
							{ x:405, y:313},
							{ x:433, y:317 },
							{ x:441, y:314 },
							{ x:446, y:320},
							{ x:451, y:326 },
							{ x:440, y:363 },
							{ x:432, y:367},
							{ x:424, y:371 },
							{ x:391, y:357 },
							{ x:354, y:369},
							{ x:317, y:381 },
							{ x:292, y:428 },
							{ x:292, y:466 },
							{ x:291, y:499 },
							{ x:299, y:521 },
							{ x:321, y:544},
							{ x:343, y:567 },
							{ x:365, y:580 },
							{ x:408, y:579},
							{ x:451, y:578 },
							{ x:488, y:543 },
							{ x:500, y:519},
							{ x:512, y:495 },
							{ x:515, y:487 },
							{ x:535, y:487},
							{ x:555, y:487 },
							{ x:575, y:498 },
							{ x:576, y:507},
							{ x:577, y:516 },
							{ x:549, y:551 },
							{ x:519, y:576},
							{ x:489, y:601 },
							{ x:440, y:621 },
							{ x:378, y:623 },
							{ x:331, y:626 },
							{ x:290, y:619 },
							{ x:249, y:596 },
							{ x:217, y:574 },
							{ x:201, y:547 },
							{ x:194, y:519},
							{ x:187, y:491 },
							{ x:189, y:462 },
							{ x:202, y:433},
							{ x:215, y:404 },
							{ x:265, y:347 },
							{ x:346, y:342 }
						];

	
	
	
	

	function is_array( mixed_var ) {	// Finds whether a variable is an array
		// 
		// +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
		// +   improved by: Legaev Andrey
		// +   bugfixed by: Cord

		return ( mixed_var instanceof Array );
	}
	function is_not_array( mixed_var ) {	// Finds whether a variable is not an array
		// 
		// +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
		// +   improved by: Legaev Andrey
		// +   bugfixed by: Cord
		// +   customized by: Emelyanov Aleksey (http://babarun.ru)

		return !( mixed_var instanceof Array );
	}
	function is_object( mixed_var ){  
		// http://kevin.vanzonneveld.net  
		//     original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)  
		//     improved by: Legaev Andrey  
		//     improved by: Michael White (http://getsprink.com)  
		// *     example 1: is_object('23');  
		// *     returns 1: false  
		// *     example 2: is_object({foo: 'bar'});  
		// *     returns 2: true  
		// *     example 3: is_object(null);  
		// *     returns 3: false  
	   
		if(mixed_var instanceof Array) {  
			return false;  
		} else {  
			return (mixed_var !== null) && (typeof( mixed_var ) == 'object');  
		}  
	}  
	function is_not_object( mixed_var ){  
		return !is_object( mixed_var );  
	}



	/*function extend( __child, __parent ) {
		var F = {};
		F.prototype = __parent.prototype;
		__child.prototype = new F()
		__child.prototype = __parent.prototype;
		__child.prototype.constructor = __child;
		__child.base = __parent.prototype;
	}*/
	function extend(Child, Parent) {
		/*var F = function() { }
		F.prototype = Parent.prototype
		Child.prototype = new F()
		Child.prototype.constructor = Child
		Child.superclass = Parent.prototype*/
		
		
		
		var __Parent = new Parent();
		Child.prototype = __Parent;
		Child.base = __Parent;
	}



    function visual_object() //базовый объект
    {
			this.trigger = function( event_sid, event_params )//подписывает на событие
			{ 		
				//console.log(event_params);
							
			
				if(this)
					if(this.events)
						if(this.events[event_sid])
							this.events[event_sid].apply( this, function(e){ return ( is_not_array(event_params) ? [event_params] : event_params ); }(event_params) ); 

				return this;	
			};
			
			this.bind = function( event_sid, event_func )//подписывает на событие
			{ 
				this.events[event_sid] = event_func;
				
				//сообщаем гланвному контейнеру, о том что на потомка было навешано какое то событие////////////////////////////////////
				//				
					//console.log( 'visual_object -> на потомка навешано событие ', event_sid	);
					this.main_container.trigger('new_event',event_sid);
				//				
				//сообщаем гланвному контейнеру, о том что на потомка было навешано какое то событие//////////////////////////////////// 
				
				return this;
			}
			
			this.unbind = function( event_sid )//отписывает от события
			{ 
				this.events[event_sid] = undefined;
								
				return this;
			}
			
			this.please_render = function()//сообщает основному контейнеру, что в модель были внесены изменения и необходимо отрендерить
			{ 		
				if(this)
					if(this.main_container)
							this.main_container.date_last_change = esboza_core.millis();

				return this;	
			};
			
			this.set_status = function(params)//устанавливает статус объекта
			{
				if(params.value)
					this.status[ params.status ] = params.value;
				else
					this.status[ params ] = true;//если значение статуса не задано тогда устанавливаем true
					
				return this;
			}
			this.get_status = function(params)//устанавливает статус объекта
			{
				if(params.status)//если в качестве параметра был передан объект
				{
					if( this.status[ params.status ] ) return this.status[ params.status ]; 
				}
				else//если в качестве параметра был передан sid статуса
				{
					if( this.status[ params ] ) return this.status[ params ];
				}
			}
			this.unset_status = function(params)//сбрасывает статус объекта
			{
				if(params.status)//если в качестве параметра был передан объект
				{
					if( this.status[ params.status ] )	this.status[ params.status ] = undefined; 
				}
				else//если в качестве параметра был передан sid статуса
				{
					if( this.status[ params ] ) this.status[ params ] = undefined;
				}
				
				return this;
			}
			/*this.set_style = function(style, value)//устанавливает статус объекта
			{
				if(style) this.style[ style ] = value;
				
				return this;
			}*/
						
			this.set_style = function()//устанавливает статус объекта
			{
					
				if(is_not_object(arguments[0]))
				{												//вызвана функция с параметрами вида  set_style('fillStyle','#000000'); 
					this.style[ arguments[0] ] = arguments[1];
					//          style            value
				}					
				else
				{												//вызвана функция с параметрами вида  set_style( {fillStyle: '#000000'}, {strokeStyle: '#000000'} ); 
					//console.log(arguments[0])
					for( arg in arguments[0] )
					{
						//console.log(arg,arguments[0][arg]);
						this.style[ arg ] = arguments[0][arg];
					}
				}
				return this;
			}
						
			this.get_style = function(style)//устанавливает статус объекта
			{
				if(style)//если в качестве параметра был передан объект
				{
					return this.style[ style ]; 
				}
				
				return this;
			}
			this.unset_style = function(style)//сбрасывает статус объекта
			{
				if(style)//если в качестве параметра был передан объект
				{
					this.style[ style ] = undefined; 
				}
				
				return this;
			}
	
			this.init = function(params)//инициализация
			{ 
					//console.log ( params);
				
					if( params instanceof Array )
					{ 
						if( params[0] )
						{
							if(params[0].sid) 			 this.sid            = params[0].sid;  
							if(params[0].main_container) this.main_container = params[0].main_container;//ссылка на главный контейнер  
						}
					}
					else
					{
						if( params ) 
						{
							if(params.sid)            this.sid            = params.sid; 
							if(params.main_container) this.main_container = params.main_container;//ссылка на главный контейнер 
						}
					} 
					

					this.evolution = 'visual_object';//история наследования
										
					this.parent = null;  //непосредственный родитель, вернёт коллекцию из одного объекта
					this.parents = [];   //все родители
					this.children = [];  //массив хранимых объектов
					this.childrens = [];  //массив хранимых объектов и их потомков(рекурсивно)
					
					this.max_x = 0;
					this.max_y = 0;
					this.min_x = 0;
					this.min_y = 0;
					
					this.position_x = 0;
					this.position_y = 0;
					this.scale_x 	= 1;
					this.scale_y 	= 1;
					this.rotate 	= 0;
					
					this.z_index = 0;
					
					this.events = []; //массив событий на которые он подписан
					this.events['render'] = function(){  /*console.log('bezier__visual_object -> events[render]');*/  };  //функция отрисовки
					this.events['render_begin'] = function(){ this.status['RENDER_NOW'] = true; };  //
					this.events['render_end'] = function(){ this.status['RENDER_NOW'] = false; };  //
					this.events['show'] = function(){}
					this.events['hide'] = function(){}
					this.events['blur'] = function(){}
					this.events['focus'] = function(){}
					this.events['focusin'] = function(){}
					this.events['focusout'] = function(){}
					this.events['load'] = function(){}
					this.events['resize'] = function(){}
					this.events['scroll'] = function(){}
					this.events['unload'] = function(){}
					this.events['click'] = function(){} //==click_left
					this.events['dblclick'] = function(){} //==dblclick_left
					this.events['click_right'] = function(){}
					this.events['dbclick_right'] = function(){}
					this.events['mousedown'] = function(){} //==mousedown_left
					this.events['mouseup'] = function(){} //==mouseup_left
					this.events['mousedown_right'] = function(){}
					this.events['mouseup_right'] = function(){}
					this.events['mousemove'] = function(){}
					this.events['mouseover'] = function(){}
					this.events['mouseout'] = function(){}
					this.events['mouseenter'] = function(){}
					this.events['mouseleave'] = function(){}
					this.events['change'] = function(){}
					this.events['select'] = function(){}
					this.events['keydown'] = function(){}
					this.events['keypress'] = function(){}
					this.events['keyup'] = function(){}
					this.events['error'] = function(){}
					
					this.status = [];//состояние объекта
					this.status['SELECTED'] = false;
					this.status['FOCUS'] = false;
					this.status['VISIBLE'] = false;
					this.status['RENDER_NOW'] = false;
					//this.status['RENDER_END'] = false;
					this.status['IS_ANIMATED'] = false; //true - если определена анимирующая функция
					this.status['PLAY'] = false;
					
					
					this.style = [];//стили 
					this.style['shadowOffsetX'] = null;//сдвиг тени по x 
					this.style['shadowOffsetY'] = null;//сдвиг тени по y
					this.style['shadowBlur'] = null;//размытие - px
					this.style['shadowColor'] = null;//css-строка цвета тени
					this.style['globalAlpha'] = null;// значения  0 || 1
					this.style['lineWidth'] = null;// толщина линии
					this.style['lineCap'] = null;// отображаемые концы линий  butt || round || square
					this.style['lineJoin'] = null;// способ соединения линий miter || round || bevel
					this.style['miterLimit'] = null;// определяет предельную толщину линии в месте соединения двух отрезков если lineJoin равен «miter»
	
			}; 
			this.init(arguments);
    }
    
	
	
	function bezier__visual_object() //коллекция - отличается от объекта тем, что trigger, bind, bind применяются не к самой коллекции, а ко всем объектам которые в ней хранятся.
    {
			this.init = function( params )//добавляет объект||коллекцию в list
			{ 
					bezier__visual_object.base.init.apply( this, params );//вызываем инициализацию предка
					this.evolution += ' ⇒ bezier__visual_object';//история наследования
					
					//console.log('INIT - bezier__visual_object', params[0]);
					this.points = (params[0].points ? params[0].points : []);
					this.draft_points = []; //просчитанне координаты с учётом scale, rotate и position
					
					this.style = [];
					//this.style['STROKE'] = params.stroke;
			};
			this.init( arguments );
			
			this.inside = function( params )//проверяет - находится ли курсор над объектом
			{ 
					//console.log('проверяет - находится ли курсор над объектом ', params, params.x, params.y);
					if( !params ) return false;
					if( !params.x || !params.y ) return false;
					if( !this.points.length > 0 ) return false;
					
					
					this.main_container.context.beginPath();
							this.main_container.context.moveTo( this.points[0].x, this.points[0].y );
							for(i=1; i<this.points.length; i++)
							{
								this.main_container.context.bezierCurveTo(
														  this.points[i].x,   this.points[i].y,
														  this.points[i+1].x, this.points[i+1].y,
														  this.points[i+2].x, this.points[i+2].y
								);
								i+=2;
							}
					this.main_container.context.closePath();
				
				
					if(
						this.main_container.context.isPointInPath( params.x, params.y)
					)
						return true;
					else
						return false;
			};

			
		
			this.events['render'] = function(){  //функция отрисовки    

                //рисуем сам сплайн//////////////////////////////////////////////////////////
                //
					//alert('render->>>>>', this);
					var i,j,ctx = this.main_container.context; //console.log(this);
					//console.log(this);
					if(this.style['fillStyle'])   ctx.fillStyle   = this.style['fillStyle'];
					if(this.style['strokeStyle']) ctx.strokeStyle = this.style['strokeStyle'];
					
                    if( this.points.length >= 4 )
                    {
						//console.log('render->>>>>', this);
						//if( this.fill )
						//{
							ctx.beginPath();
							ctx.moveTo( this.points[0].x, this.points[0].y );
							for(i=1; i<this.points.length; i++)
							{
								ctx.bezierCurveTo(
														  this.points[i].x,   this.points[i].y,
														  this.points[i+1].x, this.points[i+1].y,
														  this.points[i+2].x, this.points[i+2].y
								);
								i+=2;
							}
							//this.ctx.fillStyle = this.fillStyle;
							ctx.fill();
						//}
						
						
						//if( this.stroke )
						//{
							ctx.beginPath();
							//ctx.strokeStyle = this.strokeStyle;
							//console.log(this.strokeStyle);
							//ctx.lineWidth = "2";
							ctx.moveTo( this.points[0].x, this.points[0].y );
							for(i=1; i<this.points.length; i++)
							{
								ctx.bezierCurveTo(
														  this.points[i].x,   this.points[i].y,
														  this.points[i+1].x, this.points[i+1].y,
														  this.points[i+2].x, this.points[i+2].y
								);
								i+=2;
							}
							ctx.stroke();
						//}
                       
				
					}
				//
				//рисуем сам сплайн//////////////////////////////////////////////////////////   
				
				
				//console.log('bezier__visual_object -> events[render]'); 
				//this.main_container.date_last_change = esboza_core.millis();  
				this.main_container.date_last_render = esboza_core.millis();  
			};  
			
			
				
			/*this.events['animate'] = function(){  //функция отрисовки      
				//console.log('!!!!');
				//анимация//////////////////////////////////////////////////////////
				//
					//alert('render->>>>>', this);
					var i,j;
			  
							for(i=0; i<this.points.length; i++)
							{
								this.points[i].x+=1;   
								//this.points[i].y+=1;
							}
							
					this.main_container.date_last_change = esboza_core.millis(); 
				//
				//анимация//////////////////////////////////////////////////////////
			}*/

			
    }
	extend(bezier__visual_object, visual_object);
	
	function circle__visual_object() //коллекция - отличается от объекта тем, что trigger, bind, bind применяются не к самой коллекции, а ко всем объектам которые в ней хранятся.
    {
			this.init = function( params )//добавляет объект||коллекцию в list
			{ 
					circle__visual_object.base.init.apply( this, params );//вызываем инициализацию предка
					this.evolution += ' ⇒ circle__visual_object';//история наследования
					
					//console.log('INIT - circle__visual_object', params[0]);
					this.points = (params[0].points ? params[0].points : []);
					this.draft_points = []; //просчитанне координаты с учётом scale, rotate и position
					
					this.style = [];
					this.radius = 4;
					//this.style['STROKE'] = params.stroke;
			};
			this.init( arguments );
			
			this.inside = function( params )//проверяет - находится ли курсор над объектом
			{ 
					//console.log('проверяет - находится ли курсор над объектом ', params, params.x, params.y);
					/*if( !params ) return false;
					if( !params.x || !params.y ) return false;
					if( !this.points.length > 0 ) return false;
					
					
					this.main_container.context.beginPath();
							this.main_container.context.moveTo( this.points[0].x, this.points[0].y );
							for(i=1; i<this.points.length; i++)
							{
								this.main_container.context.bezierCurveTo(
														  this.points[i].x,   this.points[i].y,
														  this.points[i+1].x, this.points[i+1].y,
														  this.points[i+2].x, this.points[i+2].y
								);
								i+=2;
							}
					this.main_container.context.closePath();
				
				*/
					if(
						Math.abs( this.points[0].x - params.x ) <= this.radius &&  Math.abs( this.points[0].y - params.y ) <= this.radius 
					)
						return true;
					else
						return false;
			};

			
		
			this.events['render'] = function(){  //функция отрисовки    

                //рисуем сам сплайн//////////////////////////////////////////////////////////
                //
					//alert('render->>>>>', this);
					var i,j,ctx = this.main_container.context; //console.log(this);
					//console.log(this);
					if(this.style['fillStyle'])   ctx.fillStyle   = this.style['fillStyle']; else ctx.fillStyle = '#000';
					if(this.style['strokeStyle']) ctx.strokeStyle = this.style['strokeStyle']; else ctx.strokeStyle = '#000';
					
                    
					 
					ctx.beginPath();
					ctx.arc(this.points[0].x, this.points[0].y, this.radius, 0, Math.PI*2, true);
					ctx.closePath();
					ctx.fill();
									
					
				//
				//рисуем сам сплайн//////////////////////////////////////////////////////////   
				
				
				//console.log('circle__visual_object -> events[render]'); 
				//this.main_container.date_last_change = esboza_core.millis();  
				this.main_container.date_last_render = esboza_core.millis();  
			};  
			
			
				
			/*this.events['animate'] = function(){  //функция отрисовки      
				//console.log('!!!!');
				//анимация//////////////////////////////////////////////////////////
				//
					//alert('render->>>>>', this);
					var i,j;
			  
							for(i=0; i<this.points.length; i++)
							{
								this.points[i].x+=1;   
								//this.points[i].y+=1;
							}
							
					this.main_container.date_last_change = esboza_core.millis(); 
				//
				//анимация//////////////////////////////////////////////////////////
			}*/

			
    }
	extend(circle__visual_object, visual_object);
	
	function line__visual_object() //коллекция - отличается от объекта тем, что trigger, bind, bind применяются не к самой коллекции, а ко всем объектам которые в ней хранятся.
    {
			this.init = function( params )//добавляет объект||коллекцию в list
			{ 
					line__visual_object.base.init.apply( this, params );//вызываем инициализацию предка
					this.evolution += ' ⇒ line__visual_object';//история наследования
					
					//console.log('INIT - line__visual_object', params[0]);
					this.points = (params[0].points ? params[0].points : []);
					this.draft_points = []; //просчитанне координаты с учётом scale, rotate и position
					
					this.style = [];
					//this.style['STROKE'] = params.stroke;
			};
			this.init( arguments );
			
			this.inside = function( params )//проверяет - находится ли курсор над объектом
			{ 
					//console.log('проверяет - находится ли курсор над объектом ', params, params.x, params.y);
					/*if( !params ) return false;
					if( !params.x || !params.y ) return false;
					if( !this.points.length > 0 ) return false;
					
					
					this.main_container.context.beginPath();
							this.main_container.context.moveTo( this.points[0].x, this.points[0].y );
							for(i=1; i<this.points.length; i++)
							{
								this.main_container.context.bezierCurveTo(
														  this.points[i].x,   this.points[i].y,
														  this.points[i+1].x, this.points[i+1].y,
														  this.points[i+2].x, this.points[i+2].y
								);
								i+=2;
							}
					this.main_container.context.closePath();
				
				*/
					if(
						Math.abs( this.points[0].x - params.x ) <= 4 &&  Math.abs( this.points[0].y - params.y ) <= 4 
					)
						return true;
					else
						return false;
			};

			
		
			this.events['render'] = function(){  //функция отрисовки    

                //рисуем сам сплайн//////////////////////////////////////////////////////////
                //
					//alert('render->>>>>', this);
					var i,j,ctx = this.main_container.context; //console.log(this);
					//console.log(this);
					if(this.style['fillStyle'])   ctx.fillStyle   = this.style['fillStyle']; else ctx.fillStyle = '#000';
					if(this.style['strokeStyle']) ctx.strokeStyle = this.style['strokeStyle']; else ctx.strokeStyle = '#000';
					
                    //console.log(this.points[0],this.points[1]);
					if(this.points && this.points[0] && this.points[1])
					{
						
						ctx.beginPath();
						
						ctx.moveTo(this.points[1].x, this.points[1].y);
						ctx.lineTo(this.points[0].x, this.points[0].y);
						//ctx.closePath();
						ctx.stroke();
					}
					
				//
				//рисуем сам сплайн//////////////////////////////////////////////////////////   
				
				
				//console.log('line__visual_object -> events[render]'); 
				//this.main_container.date_last_change = esboza_core.millis();  
				this.main_container.date_last_render = esboza_core.millis();  
			};  
			
			
				
			/*this.events['animate'] = function(){  //функция отрисовки      
				//console.log('!!!!');
				//анимация//////////////////////////////////////////////////////////
				//
					//alert('render->>>>>', this);
					var i,j;
			  
							for(i=0; i<this.points.length; i++)
							{
								this.points[i].x+=1;   
								//this.points[i].y+=1;
							}
							
					this.main_container.date_last_change = esboza_core.millis(); 
				//
				//анимация//////////////////////////////////////////////////////////
			}*/

			
    }
	extend(line__visual_object, visual_object);
	
	function image__visual_object() //коллекция - отличается от объекта тем, что trigger, bind, bind применяются не к самой коллекции, а ко всем объектам которые в ней хранятся.
    {
			this.init = function( params )//добавляет объект||коллекцию в list
			{ 
					image__visual_object.base.init.apply( this, params );//вызываем инициализацию предка
					this.evolution += ' ⇒ image__visual_object';//история наследования
					
					this.src = null;
			};
			this.init( arguments );	
		
			this.events['render'] = function(){  console.log('image__visual_object -> events[render]'); esb.date_last_change = esboza_core.millis();  };  //функция отрисовки
    }
	extend(image__visual_object, visual_object);
	
	
	function esboza_core()
	{
		/**/
	}
	esboza_core.year = function year() { return new Date().getFullYear(); };
    esboza_core.month = function month() { return new Date().getMonth() + 1; };
    esboza_core.day = function day() { return new Date().getDate(); };
    esboza_core.hour = function hour() { return new Date().getHours(); };
    esboza_core.minute = function minute() { return new Date().getMinutes(); };
    esboza_core.second = function second() { return new Date().getSeconds(); };
    esboza_core.millis = function millis() { return new Date().getTime()/* - start*/; };

	//esboza_core.check_timer = function(){ /*console.log( esboza_core.millis() );*/ setTimeout( esboza_core.check_timer, 40 ); }; esboza_core.check_timer();
	esboza_core.types_objects = [];
	esboza_core.types_objects['bezier'] = bezier__visual_object;
	esboza_core.types_objects['circle'] = circle__visual_object;
	esboza_core.types_objects['line'] = line__visual_object;
	
	
    function collection( list ) //коллекция - отличается от объекта тем, что trigger, bind, bind применяются не к самой коллекции, а ко всем объектам которые в ней хранятся.
    {
		
			this.init = function( params )//
			{ 
				collection.base.init.apply(this,params);//вызываем инициализацию предка
				this.evolution += ' ⇒ collection';//история наследования
				
				if(list) this.list = list; else this.list = []; //список коллекций 
				this.types_objects = esboza_core.types_objects;
			};		
			this.init(arguments);

			
			this.add = function( new_object_params )//добавляет новый объект||коллекцию в list
			{ 
				new_object_params.main_container = this;//ссылка на главный контейнер
				this.list[ new_object_params.sid ] = new this.types_objects[ new_object_params.type ]( new_object_params ); return this;  
			}; 
			this.push = function( new_object )//добавляет существующий объект||коллекцию в list
			{ 
				//console.log(this);
				this.list[ new_object.sid ] = new_object; return this;  
			};			
			this.remove = function(  )
			{ 
				return this; 
			};  //удаляет объект
			
			this.find = function( q )//ищем по подстроке q названия объектов в list
			{
				var result = [];
				
				this.each(function(){
					if( this.sid == q )//найден
					{
						//console.log( this.list[sid] );
						result[ this.sid ] = this; 
					}
				});
				
				/*for( var sid in this.list )//перебираем все объекты в list
				{
					if( this.list[sid].sid == q )//найден
					{
						//console.log( this.list[sid] );
						result[ sid ] = this.list[sid] 
					}
				}*/
				return new collection( result );
			}		
			this.filter = function( func )
			{
				var result = [];
				
				for( var sid in this.list )//перебираем все объекты в list
				{
					if( func.apply( this.list[sid] ) )//условие выполнено
					{
						//console.log( this.list[sid] );
						result[ sid ] = this.list[sid] 
					}
				}
				
				return new collection( result );
			}
			
			this.each = function( func )
			{
				for( var sid in this.list )//перебираем все объекты в list
				{
					//console.log('for( var sid in this.list )', sid, this.list);
					//console.log(f);
					func.apply( this.list[sid] );
				}
				
				return this;
			}
	
			this.bind = function( event_sid, event_func )//подписывает на событие
			{ 
				//this.each(function(){ this.events[event_sid] = event_func; });
				this.each(function(){ this.bind(event_sid, event_func); });
			
				return this;
			}
			this.trigger = function( event_sid, event_params )//подписывает на событие
			{ 
				/*for( var sid in this.list )//перебираем все объекты в list
				{
					//console.log('for( var sid in this.list )', sid, this.list);
					//console.log(f);
					
					//var temp = []; temp[sid] = event_func;
					
					this.list[sid].events[event_sid].apply( this.list[sid] );
				}*/
				//console.log(event_sid, this);
				this.each(function(){ 
										/*if(this)
											if(this.events)
												if(this.events[event_sid])
													this.events[event_sid].apply( this );*/ 
										
										if(this)		
											this.trigger( event_sid, event_params );		
				});
				
				return this;
					
			}; 
	
	}
	extend(collection, visual_object);
	

    function esboza(context)
    {
			
			this.init = function( params )//добавляет объект||коллекцию в list
			{ 
				if( params instanceof Array) esboza.base.init.apply(this, params); else esboza.base.init.apply(this);//вызываем инициализацию предка
				this.evolution += ' ⇒ esboza';//история наследования
				
				this.list = []; //список коллекций 
				
				//console.log(params[0]);
				this.context = params[0].getContext('2d');//берём контекст вывода DOM модели
				this.canvas = params[0];//canvas
				
				this.date_last_render__Begin = esboza_core.millis();
				this.date_last_render__End = esboza_core.millis();
				this.date_last_render = 0;
				this.date_last_change = 1;
				this.time_last_render = 0;
				this.time_one_frame = parseInt( 1000 / 24 ); // время между сменой кадров = 1000ms / 24кадра
				
				this.frame_count = 0;
				canvas_offset = null
				
				
				this.buffers = [];//предвыбранные объекты (для ускорения)
				this.buffers['mousedown'] = new collection();//предвыбранные объекты (для ускорения)
				this.buffers['mouseup'] = new collection();//предвыбранные объекты (для ускорения)
				
				this.coordinate = [];//хранилище разнообразных координат
				
				this.default = [];//события главного контейнера которые будут вызваны если другие события не сработали
				this.always = [];//события главного контейнера которые будут вызваны всегда
			};		
			this.init(arguments);
			
			
			this.trigger = function( event_sid, event_params )//выполняет событие
			{ 		
				//if( event_sid == 'new_event' || event_sid == 'mousemove' ) console.log( 'Внутри эсбозы вызвано событие '+event_sid+ " с параметрами: ",event_params);
			
				if(this)
					if(this.events)
						if(this.events[event_sid])
						{
							if(event_params)
							{
								if( event_params instanceof Array) 
									this.events[event_sid].apply( this, event_params ); 
								else
									this.events[event_sid].apply( this, [event_params] ); 
							}
							else
								this.events[event_sid].apply( this );
						}
				return this;	
			};
			this.trigger_always = function( event_sid, event_params )//выполняет событие для событий хранящихся в this.always[]
			{ 		
				//if( event_sid == 'new_event' || event_sid == 'mousemove' ) console.log( 'Внутри эсбозы вызвано событие '+event_sid+ " с параметрами: ",event_params);
				if(this)
					if(this.always)
						if(this.always[event_sid])
						{
							if(event_params)
							{
								if( event_params instanceof Array) 
									this.always[event_sid].apply( this, event_params ); 
								else
									this.always[event_sid].apply( this, [event_params] ); 
							}
							else
								this.always[event_sid].apply( this );
						}
				return this;	
			};
			
			
			this.bind = function( event_sid, event_func )//подписывает на событие главный контейнер, а не содержащиеся в коллекции элементы (переопределяем стандартный механизм коллекций)
			{ 
				this.events[event_sid] = event_func;
				return this;
			}
			this.bind_local = function( event_sid, event_func )//подписывает на событие главный контейнер, а не содержащиеся в коллекции элементы
			{ 
				this.events[event_sid] = event_func;
				return this;
			}
			this.bind_default = function( event_sid, event_func )//подписывает на событие главный контейнер,  события будут вызваны если другие события не сработали
			{ 
				this.default[event_sid] = event_func;
				return this;
			}
			this.bind_always = function( event_sid, event_func )//подписывает на событие главный контейнер,  события будут вызваны всегда
			{ 
				this.always[event_sid] = event_func;
				return this;
			}
			

			this.check_time = function( local_this )//проверяет - не нужно ли отрендерить/изменить объекты
			{  
				//console.log('check_time -> local_this', local_this);
				////var local_this = this;
				
				
				
				
				////////setTimeout(function(){ console.log('check_time->setTimeout',local_this);  local_this.check_time.apply(local_this); }, 40);console.log('delimeter');
				
				local_this.trigger('animate');//запускаем анимацию
				
				if(
						local_this.date_last_render <= local_this.date_last_change // || true  //если после последнего рендера были внесены изменения, тогда запускаем рендер
				)
				{
				
					local_this.date_last_render__Begin = esboza_core.millis();
									
							local_this.trigger('render_begin');
							local_this.trigger('render');//.each(function(){ console.log('!!!!!!!!!!!!!!!!!'); });//рендерим все объекты
							local_this.trigger('render_end');
							local_this.date_last_render = esboza_core.millis();
					
					local_this.date_last_render__End = esboza_core.millis();
					local_this.time_last_render = local_this.date_last_render__End - local_this.date_last_render__Begin;
					
					//console.log('local_this.date_last_render__Begin',local_this.date_last_render__Begin,'date_last_render__End',local_this.date_last_render__End,'time_last_render',local_this.time_last_render,'date_last_change',local_this.date_last_change);
				}
				
				if( local_this.time_one_frame > local_this.time_last_render )//если время, за которое отрендерился последний кадр, меньше референсного времени между двумя кадрами  
				{	
					//console.log('запущен setTimeout со временем - ', ( local_this.time_one_frame - local_this.time_last_render ) );
					setTimeout( function(){ /*console.log('check_time->setTimeout',local_this);*/  local_this.check_time(local_this); }, ( local_this.time_one_frame - local_this.time_last_render )  ); 
				}
				else 
				{
					//console.log('запущен setTimeout со временем - 0 ' );
					setTimeout( function(){ /*console.log('check_time->setTimeout',local_this);*/  local_this.check_time(local_this); }, 0 );
				}
			};
			this.check_time(this);
			
			
			//this.events['click'] = function(){  this.childrens.filter(/* отбрасываем объекты не прошедшие по габаритам  */).trigger('click', {x: 10, y: 10});  };


			this.bind('render_begin', function(){		//функция отрисовки  
					this.context.save();//сохроняем состояние
					this.frame_count++;//увеличиваем счётчик кадров
					this.context.clearRect(0,0, this.context.canvas.width, this.context.canvas.height);//очищаем холст
			});
			
			
			this.events['animate'] = function(){		//функция отрисовки  
					this.each(function(){ 				
										this.trigger('animate');
					});
			}; 
			
			
			this.events['render'] = function(){		//функция отрисовки  
					this.each(function(){ 
											this.trigger('render'); 
					});
			};
			
			
			this.events['render_end'] = function(){		//функция отрисовки  
				this.context.restore();//восстонавливаем состояние
			}; 
			
			
			this.events['new_event'] = function(){		//какому-то объекту внутри коллекции добалено новое событие  
				/*
																							
					1. навешиваем обработик на DOM, (если его там нет)
					2. навешиваем обработик на esboza, (если его там нет)
						2.1 этот обработчик цепляет все объекты, которые пописанны на это событие 
				
				*/
				//console.log('new_event with arguments: ',arguments);
				switch (arguments[0]) {
								case 'mousemove': //какому-то объекту внутри коллекции добалено новое событие mousemove 
										//console.log('⌊ ','new_event with arguments: ',arguments,'inner case');
										/*
											1. навешиваем обработик "mousemove" на DOM Canvas, (если его там нет)
											2. this.events['mousemove'] = функция которая будет вызываться при срабатывании "mousemove" на DOM Canvas, и вызывать обработчики внутренних объектов, так же перед тем как она будет вызыть их, она будет отфильтровывать объекты по isPointInPath(x,y)  - .filter_by_position(x,y) || .filter_by_position_IN(x,y) || .filter_by_position_OUT(x,y) || .filter_by_position(x,y,[true||false])
										*/
										
										$(this.canvas).unbind('mousemove').bind('mousemove', function(local_this){
											return function(e){  
												local_this.trigger('mousemove', { x: e.pageX, y: e.pageY }); 
											};
										}(this));
								break
								case 'click': //какому-то объекту внутри коллекции добалено новое событие click
										/**/
										$(this.canvas).unbind('click').bind('click', function(local_this){//лишние разы навешивается события, поэтому вызывается три раза
											return function(e){ 
												local_this.trigger('click', { x: e.pageX, y: e.pageY }); 
											};
										}(this));
								break
								case 'mousedown': //какому-то объекту внутри коллекции добалено новое событие mousedown
										/**/
										$(this.canvas).unbind('mousedown').bind('mousedown', function(local_this){//лишние разы навешивается события, поэтому вызывается три раза
											return function(e){ 
												local_this.trigger('mousedown', { x: e.pageX, y: e.pageY }); 
											};
										}(this));
								break
								case 'mouseup': //какому-то объекту внутри коллекции добалено новое событие mouseup
										/**/
										$(this.canvas).unbind('mouseup').bind('mouseup', function(local_this){//лишние разы навешивается события, поэтому вызывается три раза
											return function(e){ 
												local_this.trigger('mouseup', { x: e.pageX, y: e.pageY }); 
											};
										}(this));
								break
								case 'drag': //какому-то объекту внутри коллекции добалено новое событие drag
										/**/
										$(this.canvas).unbind('mousedown').bind('mousedown', function(local_this){//лишние разы навешивается события, поэтому вызывается три раза
											return function(e){ 
												local_this.trigger('mousedown', { x: e.pageX, y: e.pageY }); 
											};
										}(this)).unbind('mousemove').bind('mousemove', function(local_this){
											return function(e){  
												local_this.trigger('mousemove', { x: e.pageX, y: e.pageY, x_old: e.pageX, y_old: e.pageY, }); 
											};
										}(this));;
								break
								default:

				}
			};
			
			this.events['mousemove'] = function(){		//функция отрисовки  
				//console.log('this внутри esboza.events[\'mousemove\']', this);

				//для тех объектов, которые сейчас отобраны в буфер, по признаку "mousedown", вызвать событие "drag"
				this.buffers['mousedown'].trigger('drag', { x: arguments[0].x, y: arguments[0].y, delta_x: ( this.coordinate['drag_start'] ? (arguments[0].x - this.coordinate['drag_start'].x) : undefined),  delta_y: ( this.coordinate['drag_start'] ? (arguments[0].y - this.coordinate['drag_start'].y) : undefined) });
				
				this.each(function(local_arguments){ 
										return function(){ 
												//console.log(local_arguments[0]);
												//точка внутри сплайна тогда вызываем  trigger "mousemove"  для этого сплайна
												if(
													this.inside({ 
																x: local_arguments[0].x, 
																y: local_arguments[0].y 
													})
												)
												{						
														if( !this.get_status('mouseover') )//если до этого курсор не находился над объектом
														{
															this.set_status('mouseover');
															//console.log(this, this.get_status('mouseover'));
															this.trigger('mouseover',{ x: local_arguments[0].x, y: local_arguments[0].y });
														}
												
														this.set_status('mousemove');
														//console.log(this.get_status('mouseover'));
														this.trigger('mousemove',{ x: local_arguments[0].x, y: local_arguments[0].y });//вызываем событие у объекта
												}
												else
												{
														if( this.get_status('mouseover') )//если до этого курсор находился над объектом
														{
															this.unset_status('mousemove');
															this.unset_status('mouseover');
															
															this.trigger('mouseout',{ x: local_arguments[0].x, y: local_arguments[0].y });
														}
												}
										};
				}(arguments));
				
				if(this.coordinate['drag_start']) this.coordinate['drag_start'] = { x: arguments[0].x, y: arguments[0].y };//обновляем координаты "drag_start" чтобы они не накапливались 
			};
			this.events['mouseover'] = function(){		//функция отрисовки  
				
				this.each(function(local_arguments){ 
										return function(){ 
												//console.log(local_arguments[0]);
												
												//точка внутри сплайна тогда вызываем  trigger "mousemove"  для этого сплайна
												if(
													this.inside({ 
																x: local_arguments[0].x, 
																y: local_arguments[0].y 
													})
												)  
												this.trigger('mouseover',{ x: local_arguments[0].x, y: local_arguments[0].y }); 
										};
				}(arguments));
			};
			this.events['mouseout'] = function(){		//функция отрисовки  
				
				this.each(function(local_arguments){ 
										return function(){ 
												//console.log(local_arguments[0]);
												
												//точка внутри сплайна тогда вызываем  trigger "mousemove"  для этого сплайна
												if(
													this.inside({ 
																x: local_arguments[0].x, 
																y: local_arguments[0].y 
													})
												)  
												this.trigger('mouseout',{ x: local_arguments[0].x, y: local_arguments[0].y }); 
										};
				}(arguments));
			};
			this.events['mousedown'] = function(){		//функция отрисовки  
				//console.log('this внутри esboza.events[\'mousedown\']', this);
				
				//this.buffers['mousedown'] = array();//потом заменить на удаление объектов, что бы не тела память
				//this.buffers['mouseup'] = array();//потом заменить на удаление объектов, что бы не тела память
				//this.clear_buffers(['mousedown','mouseup']);
				
				this.buffers['mousedown'] = new collection();
				this.coordinate['drag_start'] = { x: arguments[0].x, y: arguments[0].y };//указываем начальную точку для события "drag"
				
				this.each(function(local_arguments){ 
										return function(){ 
												//console.log('координаты mousedown - [',local_arguments[0].x, local_arguments[0].y, '] проверяем объект - ', this);
												
												//точка внутри сплайна тогда вызываем  trigger "mousedown"  для этого сплайна
												if(
													this.inside({ 
																x: local_arguments[0].x, 
																y: local_arguments[0].y 
													})
												)
												{												
													this.trigger('mousedown',{ x: local_arguments[0].x, y: local_arguments[0].y });
													
													//this.main_container.buffers['mousedown'].push(this);
													this.main_container.buffers['mousedown'].push(this);
												}
										};
				}(arguments));
				
				this.trigger_always('mousedown',{ x: arguments[0].x, y: arguments[0].y });
				
			};
			this.events['mouseup'] = function(){		//функция отрисовки  
				//console.log('this внутри esboza.events[\'mouseup\']', this);
				
				//this.buffers['mousedown'] = array();//потом заменить на удаление объектов, что бы не текла память
				//this.buffers['mouseup'] = array();//потом заменить на удаление объектов, что бы не текла память
				//this.clear_buffers(['mousedown','mouseup']);
				
				this.buffers['mousedown'] = new collection();
				delete this.buffers['mousedown_coordinate'];//удаляет координаты mousedown (используется в событие "drag" для вычисления смещения)
				
				this.each(function(local_arguments){ 
										return function(){ 
												//console.log('координаты mouseup - [',local_arguments[0].x, local_arguments[0].y, '] проверяем объект - ', this);
												
												//точка внутри сплайна тогда вызываем  trigger "mouseup"  для этого сплайна
												if(
													this.inside({ 
																x: local_arguments[0].x, 
																y: local_arguments[0].y 
													})
												)
												{												
													this.trigger('mouseup',{ x: local_arguments[0].x, y: local_arguments[0].y });
												}
										};
				}(arguments));
			};
			this.events['click'] = function(){		//функция отрисовки  
				//console.log('this внутри esboza.events[\'click\']', this);
				this.each(function(local_arguments){ 
										return function(){ 
												//console.log('координаты клика - [',local_arguments[0].x, local_arguments[0].y, '] проверяем объект - ', this);
												
												//точка внутри сплайна тогда вызываем  trigger "click"  для этого сплайна
												if(
													this.inside({ 
																x: local_arguments[0].x, 
																y: local_arguments[0].y 
													})
												)  
												this.trigger('click',{ x: local_arguments[0].x, y: local_arguments[0].y }); 
										};
				}(arguments));
			};
    }
	extend(esboza, collection);
								

	//alert('!!!!');							
	var context = document.getElementById('canvas_demo');
	
								
    var esb = new esboza(context);  
											console.log( 
															esb
															.add({ 
																	sid: 'bezier_line', 
																	type: 'bezier', 
																	points: esboza_points, 
																	stroke: true,  
																	strokeColor: '#000000',
																	//////////////////////////////////////////////////
																	//
																		//один объект
																		child:{
																				sid: 'bezier_line_inner', 
																				type: 'bezier', 
																				points: [
																							{ x: 10, y: 10}, 
																							{ x: 200, y: 20}, 
																							{ x: 30, y: 300}, 
																							{ x: 400, y: 400}
																						], 
																				stroke: true,  
																				strokeColor: '#000000',
																		},
																		//или массив объектов
																		child:[
																					{
																						sid: 'bezier_line_inner', 
																						type: 'bezier', 
																						points: [
																									{ x: 10, y: 10}, 
																									{ x: 200, y: 20}, 
																									{ x: 30, y: 300}, 
																									{ x: 400, y: 400}
																								], 
																						stroke: true,  
																						strokeColor: '#000000',
																					},
																					{
																						sid: 'bezier_line_inner', 
																						type: 'bezier', 
																						points: [
																									{ x: 10, y: 10}, 
																									{ x: 200, y: 20}, 
																									{ x: 30, y: 300}, 
																									{ x: 400, y: 400}
																								], 
																						stroke: true,  
																						strokeColor: '#000000',
																					},
																		]
																	//
																	//////////////////////////////////////////////////
															})
															.add({ 
																	sid:  'bezier_line_2', 
																	type: 'bezier',
															})
															.trigger('show') // алиас .show()
															.find('bezier_line')
															.add({ 
																	sid: 'bezier_line_22', 
																	type: 'bezier',
															})
															.each(function(){ 
																				//console.log('each:', this.sid); 
															})
															.bind('mousemove', function(params){ 
																							
																							
																							//	1. навешиваем обработик на DOM
																							//	2. навешиваем обработик на esboza, если его там нет
																							//		2.1 этот обработчик цепляет все объекты, которые пописанны на это событие 
																							
																									
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "mousemove"  с координатами:  x:'  + params.x + ', y:' + params.y);
																							//console.log('params',params);
																							
															})
															.bind('mouseover', function(params){ 
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "mouseOVER"  с координатами:  x:'  + params.x + ', y:' + params.y);	
																							//console.log( 'mouseOVER' + params.x + ' ' + params.y);
																							//console.log('params',params);
																							
																							//this.set_style('fillStyle','#eeeeee');
																							this.set_style({strokeStyle:'#eeeeee', fillStyle:'#eeeeee'});
																							this.please_render();
																							
															})
															.bind('mouseout', function(params){ 
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "mouseOUT"  с координатами:  x:'  + params.x + ', y:' + params.y);		
																							//console.log( 'mouseOUT' + params.x + ' ' + params.y);
																							//console.log('params',params);
																							
																							this.set_style('strokeStyle','#446688');
																							this.set_style('fillStyle','#888888');
																							this.please_render();
																							
															})
															.bind('click', function(params){ 
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "click"  с координатами:  x:'  + params.x + ', y:' + params.y);		
																							//console.log( 'mouseOUT' + params.x + ' ' + params.y);
																							//console.log('params',params);
																							
																							this.set_style('strokeStyle','#446688');
																							this.set_style('fillStyle','#ffee88');
																							this.please_render();
																							
															})
															//.trigger('click')
															.trigger('render')
															
											);
	
/*esb.bind_always('mousedown', function(){
	//console.log(this);
	//console.log(arguments);
	esboza_points.push({ x:arguments[0].x, y:arguments[0].y }); 
	esboza_points.push({ x:arguments[0].x, y:arguments[0].y }); 
	esboza_points.push({ x:arguments[0].x, y:arguments[0].y }); 
});*/
	
// использование Math.round() даст неравномерное распределение!
function getRandomInt(min, max)
{
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

	
													for(var pt = 0;  pt<esboza_points.length; pt++ )
													{	
														//if(pt>2) break;
														var local_sid = getRandomInt(100000,999999);
														//console.log(esboza_points[pt].x);
														
														if( (pt)%3 == 0 ) 
														{ 
															esboza_points[pt].is_base = true; 
															if(esboza_points[pt-1]) esboza_points[pt].her_first_side_point = esboza_points[pt-1]; 
															if(esboza_points[pt+1]) esboza_points[pt].her_second_side_point = esboza_points[pt+1]; 
														}
														if( (pt+1)%3 == 0 ) 
														{ 
															esboza_points[pt].is_first_side_point = true;
															if(esboza_points[pt+1]) esboza_points[pt].her_base = esboza_points[pt+1]; 
															if(esboza_points[pt+2]) esboza_points[pt].her_second_side_point = esboza_points[pt+2];
														}
														if( (pt-1)%3 == 0 ) 
														{ 
															esboza_points[pt].is_second_side_point = true;
															if(esboza_points[pt-1]) esboza_points[pt].her_base = esboza_points[pt-1]; 
															if(esboza_points[pt-2]) esboza_points[pt].her_first_side_point = esboza_points[pt-2];															
														}
														
														if(pt%3==0 || (pt+1)%3==0) esb.add({ 
																	sid: 'line_base_points__'+local_sid, 
																	type: 'line', 	
																	//points: [{ x:esboza_points[pt].x, y:esboza_points[pt].y }], 
																	points: [esboza_points[pt], esboza_points[pt+1]], 
																	stroke: true,  
																	strokeColor: '#000000',
														}).trigger('render');
														
														
														esb.add({ 
																	//sid: 'circle_base_points__'+esboza_points[pt].x+'_'+esboza_points[pt].y, 
																	sid: 'circle_base_points__'+local_sid, 
																	type: 'circle', 	
																	//points: [{ x:esboza_points[pt].x, y:esboza_points[pt].y }], 
																	points: [esboza_points[pt]], 
																	stroke: true,  
																	strokeColor: '#000000',
														});
														//console.log( 'точка на которую навешиваем событие', esb.find('circle_base_points__'+local_sid) );
														esb.find('circle_base_points__'+local_sid)
														.bind('mousemove', function(params){ //без mousemove не будут работать mouseover и mouseout
																							
																							
																							//	1. навешиваем обработик на DOM
																							//	2. навешиваем обработик на esboza, если его там нет
																							//		2.1 этот обработчик цепляет все объекты, которые пописанны на это событие 
																							
																									
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "mousemove"  с координатами:  x:'  + params.x + ', y:' + params.y);
																							//console.log('params',params);
																							
														})
														.bind('mouseover', function(params){ 
																						//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "mouseOVER"  с координатами:  x:'  + params.x + ', y:' + params.y);	
																						//console.log( 'mouseOVER' + params.x + ' ' + params.y);
																						//console.log('params',params);
																						
																						//this.set_style('fillStyle','#eeeeee');
																						this.set_style({strokeStyle:'#eeee44', fillStyle:'#ee66ee'});
																						this.please_render();
																						
																					
																						
																						this.bind('animate',function(){  //функция анимации      
																																																																				
																							if( this.radius >= 10 ) { this.unbind('animate'); return this; }
																							
																							this.radius+=2; 
																							this.please_render();
																						});
																						
																						
																						
														})
														.bind('mouseout', function(params){ 
																						//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "mouseOUT"  с координатами:  x:'  + params.x + ', y:' + params.y);		
																						//console.log( 'mouseOUT' + params.x + ' ' + params.y);
																						//console.log('params',params);
																						
																						this.set_style('strokeStyle','#006688');
																						this.set_style('fillStyle','#880088');
																						this.please_render();
																						
																						this.bind('animate',function(){  //функция анимации      
																																																																				
																							if( this.radius <= 4 ) { this.unbind('animate'); return this; }
																							
																							this.radius-=2; 
																							this.please_render();
																						});																						
														})
														.bind('click', function(params){ 
																						//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "click"  с координатами:  x:'  + params.x + ', y:' + params.y,  this);		
																						//console.log( 'mouseOUT' + params.x + ' ' + params.y);
																						//console.log('params',params);
																						
																						this.set_style('strokeStyle','#000088');
																						this.set_style('fillStyle','#ff0000');
																						this.please_render();
																						
														})
														//dragstart, dragover, drag, drop, dragend
														.bind('mousedown', function(params){ 
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "mousedown"  с координатами:  x:'  + params.x + ', y:' + params.y,  this);		
														})
														.bind('mouseup', function(params){ 
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "mouseup"  с координатами:  x:'  + params.x + ', y:' + params.y,  this);		
														})
														/*.bind('dragstart', function(params){ 
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "dragstart"  с координатами:  x:'  + params.x + ', y:' + params.y,  this);		
														})*/
														//.bind('dragover', function(params){ 
														//									//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "dragover"  с координатами:  x:'  + params.x + ', y:' + params.y,  this);		
														//})
														.bind('drag', function(params){ 
																							//console.log(params);
																							//console.log(this.points[0]);
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "drag"  с координатами:  x:'  + params.x + ', y:' + params.y,  this);
																							
																							//$('#delta_x').html(params.delta_x);
																							//$('#delta_y').html(params.delta_x);
																							
																							if( this.points[0].is_base )
																							{
																								this.points[0].x += params.delta_x;
																								this.points[0].y += params.delta_y;
																								if( this.points[0].her_first_side_point )
																								{   this.points[0].her_first_side_point.x += params.delta_x;
																									this.points[0].her_first_side_point.y += params.delta_y;	}
																								if( this.points[0].her_second_side_point )
																								{	this.points[0].her_second_side_point.x += params.delta_x;
																									this.points[0].her_second_side_point.y += params.delta_y;	}
																							}
																							if( this.points[0].is_first_side_point )
																							{
																								this.points[0].x += params.delta_x;
																								this.points[0].y += params.delta_y;
																								if( this.points[0].her_second_side_point )
																								{	this.points[0].her_second_side_point.x -= params.delta_x;
																									this.points[0].her_second_side_point.y -= params.delta_y;	}
																							}
																							if( this.points[0].is_second_side_point )
																							{
																								this.points[0].x += params.delta_x;
																								this.points[0].y += params.delta_y;
																								if( this.points[0].her_first_side_point )
																								{   this.points[0].her_first_side_point.x -= params.delta_x;
																									this.points[0].her_first_side_point.y -= params.delta_y;	}
																							}
																							
																							/*esboza_points[pt].is_base  
																							esboza_points[pt].is_first_side_point  
																							esboza_points[pt].is_second_side_point  
																							esboza_points[pt].her_first_side_point  
																							esboza_points[pt].her_second_side_point 
																							esboza_points[pt].her_base*/	
																							
																							
																							
																							
																							//this.points[0].x += params.delta_x;
																							//this.points[0].y += params.delta_y;
																							//console.log(this.points[0]);
																							this.please_render();
														})
														/*.bind('drop', function(params){ 
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "drop"  с координатами:  x:'  + params.x + ', y:' + params.y,  this);		
														})
														.bind('dragend', function(params){ 
																							//console.log( 'для объекта ' + this.sid + ' сработала функция обработчик для события "dragend"  с координатами:  x:'  + params.x + ', y:' + params.y,  this);		
														})*/
														.trigger('render');
													}
	//										
</script>
 




				






<div id="delta_x">render</div>
<div id="delta_y">render</div>
<div id="render" style="" next_color="#f00" current_color="#0f0">render</div>

</body>

</html>
